import {nanoid} from 'nanoid';
import {GisPlot, PlotTypes, PlotTextBox} from '../src';
import Websocket from './src/util/websocket';
import rescueSvg from './images/rescue_team_icon.svg';
import evacuationPoint from './images/evacuation_point_icon.png';
import materialPoint from './images/material_point_icon.png';
import medicalPoint from './images/medical_point_icon.png';
import assemblyPoint from './images/assembly_point_icon.png';
import blockingPoint from './images/blocking_point_icon.svg';
import policeCar from './images/police_car_icon.svg';
import truck from './images/truck_icon.svg';
import ambulance from './images/ambulance_icon.svg';
import fireEngine from './images/fire_engine_icon.png';
import bus from './images/bus_icon.svg';
import UAV from './images/UAV_icon.png';
import headquarters from './images/headquarters_icon.png';
import forefinger from './images/forefinger_icon.png';
import protrusion from './images/protrusion_icon.png';
import hospital from './images/hospital_icon.png';
import school from './images/school_icon.png';
import gasStation from './images/gas_station_icon.png';
import dangerous from './images/dangerous_chemicals_icon.png';
import mountain from './images/mountain_torrent_icon.png';
import landslide from './images/landslide_icon.png';
import './css/index.scss';
import {TOPIC} from './src/enum/TOPIC';
import {Point} from '../src/type';
import moment from 'moment';


const mapDom: HTMLElement = document.getElementById('map') as HTMLElement;
for (let i = mapDom.childNodes.length - 1; i >= 0; i--) {
    mapDom.removeChild(mapDom.childNodes[i]);
}
const point: Array<number> = [120.01245975494385, 30.285433530807495];
const imgUrl: string = '';//`http://t{0-6}.tianditu.com/DataServer?T=img_w&tk=a6bf5a2496115f58481b947040c83ae3&x={x}&y={y}&l={z}`;
const ciaUrl: string = '';//`http://t{0-6}.tianditu.com/DataServer?T=cia_w&tk=a6bf5a2496115f58481b947040c83ae3&x={x}&y={y}&l={z}`;
// @ts-ignore
const projection: any = ol.proj.get('EPSG:3857');
// @ts-ignore
const imgSource: any = new ol.source.XYZ({
    url: imgUrl,
    projection,
    wrapX: false
});
// @ts-ignore
const imgLayer: any = new ol.layer.Tile({
    source: imgSource
});
// @ts-ignore
const ciaSource: any = new ol.source.XYZ({
    url: ciaUrl,
    projection,
    wrapX: false
});
// @ts-ignore
const ciaLayer: any = new ol.layer.Tile({
    source: ciaSource
});
// @ts-ignore
const plotLayer: any = new ol.layer.Vector({
    // @ts-ignore
    source: new ol.source.Vector()
});
// @ts-ignore
const map = new ol.Map({
    layers: [
        imgLayer,
        ciaLayer,
        plotLayer
    ],
    target: mapDom,
    // @ts-ignore
    view: new ol.View({
        // @ts-ignore
        center: ol.proj.transform(point, 'EPSG:4326', 'EPSG:3857'),
        projection,
        zoom: 17,
        maxZoom: 19,
        minZoom: 1
    }),
    // @ts-ignore
    interactions: new ol.interaction.defaults({
        doubleClickZoom: false   //屏蔽双击放大事件
    })
});
// @ts-ignore
// console.log(map.getLayers());

map.on('click', (event: any): void => {
    const feature: any = map.forEachFeatureAtPixel(event.pixel, (feature: any): any => feature);
    if (feature && feature.get('isPlot') && !gisPlot.plotDraw.isDrawing()) {
        gisPlot.plotEdit.activate(feature);
    } else {
        gisPlot.plotEdit.deactivate();
    }
});

const ulDom: HTMLElement = document.getElementById('left-button-wrapper') as HTMLElement;
ulDom.addEventListener('click', (evt: MouseEvent): void => {
    if ((evt.target as HTMLElement).getAttribute('data-id') === PlotTypes.POINT) {
        const params: { url: any, size: Array<number> } = {url: null, size: [10, 10]};
        switch ((evt.target as HTMLElement).getAttribute('data-type')) {
            case 'rescue-team':
                params.url = rescueSvg;
                params.size = [27, 25];
                break;
            case 'evacuation-point':
                params.url = evacuationPoint;
                params.size = [40, 40];
                break;
            case 'material-point':
                params.url = materialPoint;
                params.size = [40, 40];
                break;
            case 'medical-point':
                params.url = medicalPoint;
                params.size = [40, 40];
                break;
            case 'assembly-point':
                params.url = assemblyPoint;
                params.size = [43, 40];
                break;
            case 'blocking-point':
                params.url = blockingPoint;
                params.size = [12, 5];
                break;
            case 'police-car':
                params.url = policeCar;
                params.size = [30, 27];
                break;
            case 'truck':
                params.url = truck;
                params.size = [31, 25];
                break;
            case 'ambulance':
                params.url = ambulance;
                params.size = [30, 25];
                break;
            case 'fire-engine':
                params.url = fireEngine;
                params.size = [45, 40];
                break;
            case 'bus':
                params.url = bus;
                params.size = [25, 29];
                break;
            case 'UAV':
                params.url = UAV;
                params.size = [40, 40];
                break;
            case 'headquarters':
                params.url = headquarters;
                params.size = [40, 40];
                break;
            case 'forefinger':
                params.url = forefinger;
                params.size = [40, 40];
                break;
            case 'protrusion':
                params.url = protrusion;
                params.size = [40, 40];
                break;
            case 'hospital':
                params.url = hospital;
                params.size = [40, 40];
                break;
            case 'school':
                params.url = school;
                params.size = [40, 40];
                break;
            case 'gas-station':
                params.url = gasStation;
                params.size = [40, 40];
                break;
            case 'dangerous':
                params.url = dangerous;
                params.size = [40, 40];
                break;
            case 'mountain':
                params.url = mountain;
                params.size = [42, 40];
                break;
            case 'landslide':
                params.url = landslide;
                params.size = [40, 40];
                break;
        }
        activate((evt.target as HTMLElement).getAttribute('data-id') as PlotTypes, params);
    } else {
        switch ((evt.target as HTMLElement).id) {
            case PlotTypes.TEXT_AREA:
                activate(PlotTypes.TEXT_AREA);
                break;
            case PlotTypes.CURVE:
                activate(PlotTypes.CURVE);
                break;
            case PlotTypes.ARC:
                activate(PlotTypes.ARC);
                break;
            case PlotTypes.CIRCLE:
                activate(PlotTypes.CIRCLE, {
                    strokeColor: 'rgb(255,128,30)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(255,0,255)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.FREE_HAND_LINE:
                activate(PlotTypes.FREE_HAND_LINE, {
                    color: 'rgb(255, 34, 125)',
                    weight: 2,
                    opacity: 0.8,
                    style: 'solid'
                });
                break;
            case PlotTypes.SEGMENT_LINE:
                activate(PlotTypes.SEGMENT_LINE, {
                    color: 'rgb(44,54,237)',
                    weight: 3,
                    opacity: 0.8,
                    style: 'solid'
                });
                break;
            case PlotTypes.POLYLINE:
                activate(PlotTypes.POLYLINE, {
                    color: 'rgb(232,204,20)',
                    weight: 3,
                    opacity: 0.8,
                    style: 'solid'
                });
                break;
            case PlotTypes.RECTANGLE:
                activate(PlotTypes.RECTANGLE, {
                    strokeColor: 'rgb(255, 125, 60)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(255, 255, 0)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.POLYGON:
                activate(PlotTypes.POLYGON, {
                    strokeColor: 'rgb(125, 255, 60)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(255, 255, 0)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.ELLIPSE:
                activate(PlotTypes.ELLIPSE);
                break;
            case PlotTypes.LUNE:
                activate(PlotTypes.LUNE);
                break;
            case PlotTypes.SECTOR:
                activate(PlotTypes.SECTOR);
                break;
            case PlotTypes.CLOSED_CURVE:
                activate(PlotTypes.CLOSED_CURVE);
                break;
            case PlotTypes.FREE_POLYGON:
                activate(PlotTypes.FREE_POLYGON);
                break;
            case PlotTypes.GATHERING_PLACE:
                activate(PlotTypes.GATHERING_PLACE);
                break;
            case PlotTypes.DOUBLE_ARROW:
                activate(PlotTypes.DOUBLE_ARROW, {
                    strokeColor: 'rgb(255, 0, 0)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(152,18,218)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.STRAIGHT_ARROW:
                activate(PlotTypes.STRAIGHT_ARROW, {
                    strokeColor: 'rgb(41,193,7)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(246,42,90)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.FINE_ARROW:
                activate(PlotTypes.FINE_ARROW, {
                    strokeColor: 'rgb(13,244,217)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(218,33,8)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.ATTACK_ARROW:
                activate(PlotTypes.ATTACK_ARROW);
                break;
            case PlotTypes.ASSAULT_DIRECTION:
                activate(PlotTypes.ASSAULT_DIRECTION);
                break;
            case PlotTypes.TAILED_ATTACK_ARROW:
                activate(PlotTypes.TAILED_ATTACK_ARROW);
                break;
            case PlotTypes.SQUAD_COMBAT:
                activate(PlotTypes.SQUAD_COMBAT, {
                    strokeColor: 'rgb(227,136,15)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(71,220,239)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.TAILED_SQUAD_COMBAT:
                activate(PlotTypes.TAILED_SQUAD_COMBAT);
                break;
            case PlotTypes.RECT_FLAG:
                activate(PlotTypes.RECT_FLAG, {
                    strokeColor: 'rgb(255, 0, 0)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(255, 0, 125)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.TRIANGLE_FLAG:
                activate(PlotTypes.TRIANGLE_FLAG, {
                    strokeColor: 'rgb(255, 0, 0)',
                    strokeWeight: 2,
                    strokeOpacity: 0.5,
                    strokeStyle: 'solid',
                    fillColor: 'rgb(255, 0, 125)',
                    fillOpacity: 0.3
                });
                break;
            case PlotTypes.CURVE_FLAG:
                activate(PlotTypes.CURVE_FLAG);
                break;
            case 'createPlot':
                createPlot();
                break;
            case 'sharePlot':
                sharePlot();
                break;
            case 'endPlot':
                endPlot();
                break;
            default:
                break;
        }
    }
});

let socket: Websocket;
let accountId: string = nanoid();
let plotId: string = '3727501b-c0d0-4bd6-b8d7-0150bece023b';

const debugServer = (): void => {
    console.log(plotId);
    const websocketUrl = `ws://192.168.130.78:8094/cooper-draw-server/scooper/plot?accountName=Test01&accountId=${accountId}&token=123123123&plotId=${plotId}`;
    socket = new Websocket(websocketUrl, {debug: true});
    socket.open();
    socket.onConnectSuccess = (): void => {
        console.log('连接成功的后继操作');
    };
    socket.onMessage = (data: any): void => {
        console.log('收到消息：', data);
        if (data.topic === TOPIC.INSTRUCT) {
            if (data.instructType) {
                const plotType: string = data.instructContent.type;
                if (data.instructContent && data.instructType === 'ADD') {
                    let geometry: any = null;
                    if (plotType === 'point') {
                        geometry = gisPlot.plotDraw.createPlot(data.instructContent.type as PlotTypes, [data.instructContent.point], {});
                    } else if (plotType === 'text') {
                        const {width, height}: { width: number, height: number } = data.instructContent;
                        const plotText: PlotTextBox = new PlotTextBox({
                            id: data.instructContent.id,
                            position: data.instructContent.position,
                            value: '',
                            width,
                            height,
                            style: {
                                width: `${width}px`,
                                height: `${height}px`
                            }
                        });
                        map.addOverlay(plotText);
                        return;
                    } else {
                        geometry = gisPlot.plotDraw.createPlot(data.instructContent.type as PlotTypes, data.instructContent.path, data.instructContent.style);
                    }
                    const feature = new ol.Feature(geometry);
                    feature.set('isPlot', true);
                    feature.set('plotType', data.instructContent.type);
                    feature.set('id', data.instructContent.id);
                    const style: any = gisPlot.plotDraw.createStyle(data.instructContent.type as PlotTypes, data.instructContent.style);
                    feature.setStyle(style);
                    plotLayer.getSource().addFeature(feature);
                } else if (data.instructContent && data.instructType === 'MOVE') {
                    const currentEditFeature: any = plotLayer.getSource().getFeatures().find((feature: any): any => {
                        return feature.getProperties().id === data.instructContent.id;
                    });
                    const geometry: any = currentEditFeature.getGeometry();
                    let newPoints: Array<Point> = [];
                    if (plotType === 'point') {
                        newPoints = [data.instructContent.point];
                    } else if (plotType === 'text') {

                    } else {
                        newPoints = data.instructContent.path;
                    }
                    geometry.setPoints(newPoints);
                }
            }
        }
    };

    socket.onClose = (): void => {
        console.log('关闭socket了');
    };
};

const createPlot = (): void => {
    const request = new Request('http://192.168.130.204:8080/cooper-draw-server/api/data/createPlot', {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        method: 'post',
        body: `name='测试标绘01'&createId=${nanoid()}`
    });

    fetch(request).then(response => response.json()).then(res => {
        if (res.code === 0) {
            const {plotBaseInfo} = res.data;
            // plotId = plotBaseInfo.id;
            // console.log(plotId);
            const websocketUrl = `ws://192.168.130.204:8080/cooper-draw-server/scooper/plot?accountName=Test01&accountId=${accountId}&token=123123123&plotId=${plotId}`;
            socket = new Websocket(websocketUrl, {debug: true});
            socket.open();
            socket.onConnectSuccess = (): void => {
                console.log('连接成功的后继操作');
            };
            socket.onMessage = (data: any): void => {
                console.log('收到消息：', data);
                if (data.topic === TOPIC.INSTRUCT) {
                    if (data.instructType) {
                        const plotType: string = data.instructContent.type;
                        if (data.instructContent && data.instructType === 'ADD') {
                            let geometry: any = null;
                            if (plotType === 'point') {
                                geometry = gisPlot.plotDraw.createPlot(data.instructContent.type as PlotTypes, [data.instructContent.point], {});
                            } else if (plotType === 'text') {
                                const {width, height}: { width: number, height: number } = data.instructContent;
                                const plotText: PlotTextBox = new PlotTextBox({
                                    id: data.instructContent.id,
                                    position: data.instructContent.position,
                                    value: '',
                                    width,
                                    height,
                                    style: {
                                        width: `${width}px`,
                                        height: `${height}px`
                                    }
                                });
                                map.addOverlay(plotText);
                                return;
                            } else {
                                geometry = gisPlot.plotDraw.createPlot(data.instructContent.type as PlotTypes, data.instructContent.path, data.instructContent.style);
                            }
                            const feature = new ol.Feature(geometry);
                            feature.set('isPlot', true);
                            feature.set('plotType', data.instructContent.type);
                            feature.set('id', data.instructContent.id);
                            const style: any = gisPlot.plotDraw.createStyle(data.instructContent.type as PlotTypes, data.instructContent.style);
                            feature.setStyle(style);
                            plotLayer.getSource().addFeature(feature);
                        } else if (data.instructContent && (data.instructType === 'MOVE' || data.instructType === 'DEFORMATION')) {
                            const currentEditFeature: any = plotLayer.getSource().getFeatures().find((feature: any): any => {
                                return feature.getProperties().id === data.instructContent.id;
                            });
                            const geometry: any = currentEditFeature.getGeometry();
                            let newPoints: Array<Point> = [];
                            if (plotType === 'point') {
                                newPoints = [data.instructContent.point];
                            } else if (plotType === 'text') {

                            } else {
                                newPoints = data.instructContent.path;
                            }
                            geometry.setPoints(newPoints);
                        }
                    }
                }
            };

            socket.onClose = (): void => {
                console.log('关闭socket了');
            };
        }
    });
};

const sharePlot = (): void => {

};

const endPlot = (): void => {
    console.log('end plot');
};

const gisPlot: GisPlot = new GisPlot(map, {isClear: true});
// const gisPlot: GisPlot = new GisPlot(map, {zoomToExtent: true});
gisPlot.plotDraw.addListener('drawEnd', (event: any): void => {
    // gisPlot.plotEdit.activate(event.feature);
    if (event.plotType && event.plotType === 'text') { // 文本
        const params = {
            topic: 'instruct',
            plotid: plotId,
            accountId: accountId,
            updateTime: moment(Number(new Date().getTime())).format('YYYY-MM-DD HH:mm:ss.SSS'),
            mapType: '1',
            instructType: 'ADD',
            instructContent: {
                id: nanoid(),
                type: 'text',
                ...event.data
            }
        };
        // socket.send(params);
    } else {
        const {plotType}: { plotType: string } = event.feature.getProperties();
        const params = {
            topic: 'instruct',
            plotid: plotId,
            accountId: accountId,
            updateTime: moment(Number(new Date().getTime())).format('YYYY-MM-DD HH:mm:ss.SSS'),
            mapType: '1',
            instructType: 'ADD',
            instructContent: {
                id: nanoid(),
                type: plotType,
                ...event.data
            }
        };
        socket.send(params);
    }
});

gisPlot.plotEdit.addListener('moveEnd', (event: any): void => {
    console.log(event.feature.getProperties().id, event.feature.getProperties().plotType);
    const plotType: string = event.feature.getProperties().plotType;
    const id: string = event.feature.getProperties().id;
    const params = {
        topic: 'instruct',
        plotid: plotId,
        accountId: accountId,
        updateTime: moment(Number(new Date().getTime())).format('YYYY-MM-DD HH:mm:ss.SSS'),
        mapType: '1',
        instructType: 'MOVE',
        instructContent: {
            id,
            type: plotType,
            ...event.data
        }
    };
    socket.send(params);
});

gisPlot.plotEdit.addListener('deformationEnd', (event: any): void => {
    const plotType: string = event.feature.getProperties().plotType;
    const id: string = event.feature.getProperties().id;
    const params = {
        topic: 'instruct',
        plotid: plotId,
        accountId: accountId,
        updateTime: moment(Number(new Date().getTime())).format('YYYY-MM-DD HH:mm:ss.SSS'),
        mapType: '1',
        instructType: 'DEFORMATION',
        instructContent: {
            id,
            type: plotType,
            ...event.data
        }
    };
    socket.send(params);
});

const activate = (type: PlotTypes, params?: any): void => {
    gisPlot.plotEdit.deactivate();
    gisPlot.plotDraw.activate(type, params);
};